package com.mo.common.aop;

import java.util.Date;

import org.apache.log4j.Logger;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.danga.MemCached.MemCachedClient;
import com.mo.config.properties.BaseInfoProperties;

//定义切面
@Aspect
@Component
public class MemcacheAspect {
	private static Logger logger = Logger.getLogger(MemcacheAspect.class);
//	private static final String[] cacheKeys = { "searchContPageList","getContPlayUrl"};// ,"InitIndex","QueryContentsForMi"
//	private static final List<String> keylist = Arrays.asList(cacheKeys);
//	
//	private static final String[] needSiteIdCacheKeys = {
//		"getQuitReContList","getRankingReContList","getScreeningList",
//		"getSearchReContList", "getTopMenuList","getSubMenuContList"};
//	private static final List<String> needSiteIdlist = Arrays.asList(needSiteIdCacheKeys);
//
//	private static final String[] distinguishRegionsCacheKeys = { 
//		"getTopMenuList","getSubMenuContList","getContPageList"};
	//getContPageList该接口存在两个分别在cont和label两个controller
	//如果有机会，希望能改掉该方法名称
	//因为名称相同就要区分地域缓存，接口参数中必须包含request参数
	
//	private static final List<String> distinguishRegions = Arrays.asList(distinguishRegionsCacheKeys);
	
	@Autowired
	private MemCachedClient memCachedClient;

	/**
	 * 拦截所有元注解MemCache注解的方法
	 */
	@Pointcut("@annotation(com.mo.common.annotion.MemCache)")
	public void pointcutMethod() {
	}

	/**
	 * After com.zhilink.tv.action包下所有类 的execute方法
	 * 
	 * @param jp
	 */
	@Around("pointcutMethod()")
	public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {
		logger.info("doAround start");
		// 前置：从memcache里获取缓存
		// 先获取目标方法参数
		long startTime = System.currentTimeMillis();
		String applId = "";
		Object[] args = joinPoint.getArgs();
		if (args != null && args.length > 0) {
			for(int i=0;i<args.length;i++){
				if(args[i]!=null){
					String target = args[i].toString();
					applId = target.split("@")[0]+"-"+applId;
				}
			}
			applId = applId.substring(0,applId.length()-1);
		}
		// 获取目标方法所在类
		String target = joinPoint.getTarget().toString();
		String className = target.split("@")[0];
		// 获取目标方法的方法名称
		String methodName = joinPoint.getSignature().getName();
		// memcache中key格式： applId:方法名称
		String cacheKey = applId + "-" + className + "." + methodName;
		//处理特殊的cachekey
//		cacheKey = cacheKey + getCacheKey(args, methodName);
		
		Object obj=null;
		if(baseInfoProperties.isUseMemcache()){
			obj = memCachedClient.get(cacheKey);
			if (obj != null) {
				logger.info("**********从memcache中查到了数据**********");
				logger.info("cacheKey的KEY值:" + cacheKey);
				logger.info("memcache的VALUE值:" + obj.toString());
				return obj;
			}
			long endTime = System.currentTimeMillis();
			logger.info("memcache缓存AOP处理所用时间:" + (endTime - startTime));
			logger.info("**********没有从memcache查到数据**********");
		}
		
		try {
			logger.info("**********开始从MySQL查询数据**********"); 
			obj = joinPoint.proceed();
		} catch (Throwable e) {
			e.printStackTrace();
		}
		
		 //后置：将数据库查到的数据保存到memcache 
//		byte[] bytes = SerializeUtil.serialize(obj);
		if(baseInfoProperties.isUseMemcache()){
			 boolean boo = memCachedClient.add(cacheKey,obj, new Date( 10*60*1000 )); //10*60*1000
			 if(boo){ 
				 logger.info("**********数据成功保存到memcache缓存!!!**********"); 
				 logger.info("memcache的KEY值:"+cacheKey); 
				 logger.info("memcache的VALUE值:"+obj.toString()); 
			 } 
		}
		 return obj;
	
	}

//	@Resource
//    private IRegionService regionService;
	@Autowired
	protected BaseInfoProperties baseInfoProperties;
	
	/*String getCacheKey(Object[] args,String methodName){
		if(args.length==0){
			return "";
		}
		String cacheKey="";
		HttpServletRequest request = null;
		if(needSiteIdlist.contains(methodName)){
			request = request==null?(HttpServletRequest) args[0]:request;
			cacheKey =  cacheKey+"#siteId:" + request.getAttribute("siteId")+"";
		}
		if(distinguishRegions.contains(methodName)){
			request = request==null?(HttpServletRequest) args[0]:request;
			if(baseInfoProperties.getUseRegionColumns()){
				try {
					String ipStr = IpUtil.getRemoteIpAddr(request);
					if(ipStr==null || "127.0.0.1".equals(ipStr)){
						ipStr = baseInfoProperties.getDefaultRegion();//"106.38.36.34";//默认北京
					}
					Long ipNum = IpUtil.ip2long(ipStr);
					Region region = regionService.getRegionByIpNum(ipNum);
					cacheKey =  cacheKey+ "#region"+ (region==null?"":region.toString());  
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}
		if (keylist.contains(methodName)) {
			request = request==null?(HttpServletRequest) args[0]:request;
			try {
				String pStr = getParameterStr(request, methodName);
				cacheKey = cacheKey + "#" + pStr;
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		return cacheKey;
	}*/

//	@Autowired
//    StringRedisTemplate stringRedisTemplate;
	/*String getParameterStr(HttpServletRequest request,String methodName) throws Exception{
		String pStr = "";
		
		if("searchContPageList".equals(methodName)){
			pStr += ">"+request.getParameter("keyword");
			pStr += ">"+request.getParameter("label_id");
			pStr += ">"+request.getParameter("c_area");
			pStr += ">"+request.getParameter("c_origin");
			pStr += ">"+request.getParameter("c_type");
			pStr += ">"+request.getParameter("c_level");
			pStr += ">"+request.getParameter("c_priceSection");
			pStr += ">"+request.getParameter("c_brand");
			pStr += ">"+request.getParameter("c_sellStatus");
			pStr += ">"+request.getParameter("current");
		}
		if("getContPlayUrl".equals(methodName)){
			String type = request.getParameter("type");
			Long contId = Long.parseLong(request.getParameter("contId"));
			String bitRate = request.getParameter("bitRate");
			pStr += ">"+type;
			pStr += ">"+contId;
			pStr += ">"+bitRate;
			ProcessingPlaybackVolume(request, type, contId);
		}
		return pStr;
	}*/


	/*void ProcessingPlaybackVolume(HttpServletRequest request,String type,Long contId) throws Exception{
		if(type!=null&&type!=""&&"15".equals(type)){//直播时需要统计各地域的播放量
			Long ipNum = IpUtil.ip2long(IpUtil.getRemoteIpAddr(request));
			//Long ipNum = IpUtil.ip2long("124.115.6.19");
			Region region = regionService.getRegionByIpNum(ipNum);
			if(region!=null){
				String regionName = null;
				String parentName = region.getParentName();
				if(parentName!=null&&parentName!=""){
					regionName=parentName;
				}else{
					regionName=region.getName();
				}
				Boolean hasKey = stringRedisTemplate.hasKey(String.format(TV_SYS_KEY.TV_SYS_CONT_LIVE_COUNT_INFO, contId));
				if(hasKey){
					Double score = stringRedisTemplate.opsForZSet().score(String.format(TV_SYS_KEY.TV_SYS_CONT_LIVE_COUNT_INFO, contId), regionName);
					if(score!=null&&score>0){
						stringRedisTemplate.opsForZSet().add(String.format(TV_SYS_KEY.TV_SYS_CONT_LIVE_COUNT_INFO, contId), regionName, score+1);
					}else{
						stringRedisTemplate.opsForZSet().add(String.format(TV_SYS_KEY.TV_SYS_CONT_LIVE_COUNT_INFO, contId), regionName, 1);
					}	
					
					String string = stringRedisTemplate.opsForValue().get(String.format(TV_SYS_KEY.TV_SYS_CONT_LIVE_ALL_ONLINE_COUNT_INFO, contId));
					if(StringUtils.isEmpty(string)){
						string="0";
					}
					stringRedisTemplate.opsForValue().set(String.format(TV_SYS_KEY.TV_SYS_CONT_LIVE_ALL_ONLINE_COUNT_INFO, contId), Double.parseDouble(string)+1+"");
				}else{
					String key=String.format(TV_SYS_KEY.TV_SYS_CONT_LIVE_COUNT_INFO, contId);
					stringRedisTemplate.opsForZSet().add(key, regionName, 1);
					String allKey=String.format(TV_SYS_KEY.TV_SYS_CONT_LIVE_ALL_ONLINE_COUNT_INFO, contId);
					stringRedisTemplate.opsForValue().set(allKey, "1");
				}
				
			}
		}
		String count = stringRedisTemplate.opsForValue().get(String.format(TV_SYS_KEY.TV_SYS_CONT_PLAYCOUNT_INFO, contId));
		if(count!=null&&count!=""){
			count=(Integer.parseInt(count)+1)+"";
		}else{
			count="1";
		}
		stringRedisTemplate.opsForValue().set(String.format(TV_SYS_KEY.TV_SYS_CONT_PLAYCOUNT_INFO, contId), count);
	}*/

}
